//
//  CZStatusDAL.swift
//  GZWeibo009
//
//  Created by gzxzmac on 16/4/6.
//  Copyright © 2016年 gzxzmac. All rights reserved.
//

import UIKit

/*
    专门加载数据:
        1.从本地数据库加载
        2.从网络
*/
class CZStatusDAL: NSObject {
    static let sharedDAL = CZStatusDAL()
    
    private override init() {
        super.init()
    }
    
    /// 数据过期时间
    let cacheDataTime: NSTimeInterval = 60 // 7 * 24 * 60 * 60 // 7 天
    
    /// 定期清理过期的数据
    func clearCacheData() {
        // 计算过期时间
        let overDate = NSDate(timeIntervalSinceNow: -cacheDataTime)
        
        //
        let df = NSDateFormatter()
        df.locale = NSLocale(localeIdentifier: "EN")
        df.dateFormat = "yyyy-MM-dd HH:mm:ss"
        let overTime = df.stringFromDate(overDate)
        print("overTime: \(overTime)")
        
        let sql = "DELETE FROM T_Status WHERE createTime < '\(overTime)';"
        print("清除sql: \(sql)")
        
        CZSQLiteManager.sharedManager.dbQueue.inDatabase { (db) -> Void in
            do {
                try db.executeUpdate(sql, values: [])
                print("清除缓存成功了")
            } catch let error as NSError {
                print("清除缓存失败了: \(error)")
            }
        }
    }
    
    /**
     数据访问层加载微博数据
     */
    func dalLoadStatus(since_id: Int64, max_id: Int64, dalLoadStatusCallback: (status: [[String: AnyObject]]?, error: NSError?) -> ()) {
        // 1.先去本地数据加载 *
        loadCacheStatus(since_id, max_id: max_id) { (statuses, error) -> () in
            if statuses != nil && statuses?.count > 0 {
                // 2.如果本地加载到数据,直接返回数据
                // 返回
                CZPrint(msg: "加载本地微博数据")
                dalLoadStatusCallback(status: statuses, error: nil)
                return
            }
            
            // 3.如果本地没有数据,使用网络工具类加载网络数据
            // url
            let urlString = "https://api.weibo.com/2/statuses/home_timeline.json"
            
            // 请求参数
            var parameters = [String: AnyObject]()
            
            // 表示别人传递了since_id需要下拉刷新,返回比since_id大的微博
            // 注意: 字典里面的key不能直接传递Int64
            if since_id > 0 {
                parameters["since_id"] = NSNumber(longLong: since_id)
            } else if max_id > 0 {
                // 比人传递了max_id.添加到字典里面
                parameters["max_id"] = NSNumber(longLong: max_id - 1)
            }
            
            // 使用网络工具的加载微博数据
            CZNetworkTool.sharedInstance.requestGET(urlString, parameters: parameters, requestCallback: { (result, error) -> () in
                if error != nil {
                    // 网络请求失败
                    // 失败
                    CZPrint(msg: "加载微博网络请求失败: \(error)")
                    dalLoadStatusCallback(status: nil, error: error)
                    return
                }
                
                let statusesArray = result?["statuses"] as? [[String: AnyObject]]
                
                if statusesArray != nil {
                    // 4.将加载的网络数据保存到本地 *
                    self.saveStatus(statusesArray!)
                    
                    // 5.将加载的网络数据返回
                    dalLoadStatusCallback(status: statusesArray, error: nil)
                } else {
                    dalLoadStatusCallback(status: nil, error: nil)
                }
            })
        }
    }
    
    /// 从本地数据加载微博数据
    private func loadCacheStatus(since_id: Int64, max_id: Int64, loadCachedFinished: (statuses: [[String: AnyObject]]?, error: NSError?) -> ()) {
        let userId = CZUserAccountViewModel.sharedInstance.userAccount?.uid
        assert(userId != nil, "没有UID")
        
        var sql = "SELECT status FROM T_Status \n"
        
        if since_id > 0 {
            sql += "WHERE statusId > \(since_id) AND userId = \(Int(userId!)!) \n"
        } else if max_id > 0 {
            sql += "WHERE statusId < \(max_id) AND userId = \(Int(userId!)!) \n"
        } else {
            sql += "WHERE userId = \(Int(userId!)!) \n"
        }
        
        sql += "ORDER BY statusId DESC LIMIT 20"
//        print("加载微博的sql: \(sql)")
        
        CZSQLiteManager.sharedManager.dbQueue.inDatabase { (db) -> Void in
            do {
                let result = try db.executeQuery(sql, values: [])
                
                var statuses = [[String: AnyObject]]()
                
                while result.next() {
                    // 获取微博数据,字符串
                    let string = result.stringForColumn("status")
                    
                    // 将String -> NSData -> 字典
                    let data = string.dataUsingEncoding(NSUTF8StringEncoding)!
                    let dict = try! NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions(rawValue: 0)) as! [String: AnyObject]
                    statuses.append(dict)
                }
                
                // 告诉调用的人本地加载到数据了
                loadCachedFinished(statuses: statuses, error: nil)
            } catch let error as NSError {
                print("加载缓存数据出错了:\(error)")
                loadCachedFinished(statuses: nil, error: error)
            }
        }
    }
    
    /**
     保存微博数据
     
     - parameter statuses: 微博字典数据,最终将每个微博字典保存到数据库
     */
    private func saveStatus(statuses: [[String: AnyObject]]) {
        let userId = CZUserAccountViewModel.sharedInstance.userAccount?.uid
        assert(userId != nil, "没有UID")
        
        // 准备sql语句
        let sql = "INSERT INTO T_Status (statusId, status, userId) VALUES (?, ?, ?)"
        
        CZSQLiteManager.sharedManager.dbQueue.inTransaction { (db, rollback) -> Void in
            
            do {
                // 遍历获取每一条微博字典
                for dict in statuses {
                    // 微博id
                    let statusId = dict["id"] as! Int
                    
                    // 数据库中不能直接存储字典
                    // 字典转成 -> NSData -> String
                    let data = try! NSJSONSerialization.dataWithJSONObject(dict, options: NSJSONWritingOptions(rawValue: 0))
                    let status = String(data: data, encoding: NSUTF8StringEncoding)!
                    
                    try db.executeUpdate(sql, values: [statusId, status, Int(userId!)!])
                }
                print("保存了:\(statuses.count)条数据到数据库")
            } catch let error as NSError {
                print("保存微博数据失败:\(error)")
            }
        }
    }
}
